home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / sail.tar / sail / dr_1.c < prev    next >
C/C++ Source or Header  |  1992-09-18  |  10KB  |  441 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that this notice is preserved and that due credit is given
  7.  * to the University of California at Berkeley. The name of the University
  8.  * may not be used to endorse or promote products derived from this
  9.  * software without specific prior written permission. This software
  10.  * is provided ``as is'' without express or implied warranty.
  11.  */
  12.  
  13. #ifndef lint
  14. static char sccsid[] = "@(#)dr_1.c    5.2 (Berkeley) 3/9/88";
  15. #endif /* not lint */
  16.  
  17. #include "driver.h"
  18.  
  19. unfoul()
  20. {
  21.     register struct ship *sp;
  22.     struct ship *to;
  23.     register int nat;
  24.     register i;
  25.  
  26.     foreachship(sp) {
  27.         if (sp->file->captain[0])
  28.             continue;
  29.         nat = capship(sp)->nationality;
  30.         foreachship(to) {
  31.             if (nat != capship(to)->nationality &&
  32.                 !toughmelee(sp, to, 0, 0))
  33.                 continue;
  34.             for (i = fouled2(sp, to); --i >= 0;)
  35.                 if (die() <= 2)
  36.                     cleanfoul(sp, to, 0);
  37.         }
  38.     }
  39. }
  40.  
  41. boardcomp()
  42. {
  43.     int crew[3];
  44.     register struct ship *sp, *sq;
  45.  
  46.     foreachship(sp) {
  47.         if (*sp->file->captain)
  48.             continue;
  49.         if (sp->file->dir == 0)
  50.             continue;
  51.         if (sp->file->struck || sp->file->captured != 0)
  52.             continue;
  53.         if (!snagged(sp))
  54.             continue;
  55.         crew[0] = sp->specs->crew1 != 0;
  56.         crew[1] = sp->specs->crew2 != 0;
  57.         crew[2] = sp->specs->crew3 != 0;
  58.         foreachship(sq) {
  59.             if (!Xsnagged2(sp, sq))
  60.                 continue;
  61.             if (meleeing(sp, sq))
  62.                 continue;
  63.             if (!sq->file->dir
  64.                 || sp->nationality == capship(sq)->nationality)
  65.                 continue;
  66.             switch (sp->specs->class - sq->specs->class) {
  67.             case -3: case -4: case -5:
  68.                 if (crew[0]) {
  69.                     /* OBP */
  70.                     sendbp(sp, sq, crew[0]*100, 0);
  71.                     crew[0] = 0;
  72.                 } else if (crew[1]){
  73.                     /* OBP */
  74.                     sendbp(sp, sq, crew[1]*10, 0);
  75.                     crew[1] = 0;
  76.                 }
  77.                 break;
  78.             case -2:
  79.                 if (crew[0] || crew[1]) {
  80.                     /* OBP */
  81.                     sendbp(sp, sq, crew[0]*100+crew[1]*10,
  82.                         0);
  83.                     crew[0] = crew[1] = 0;
  84.                 }
  85.                 break;
  86.             case -1: case 0: case 1:
  87.                 if (crew[0]) {
  88.                     /* OBP */
  89.                     sendbp(sp, sq, crew[0]*100+crew[1]*10,
  90.                         0);
  91.                     crew[0] = crew[1] = 0;
  92.                 }
  93.                 break;
  94.             case 2: case 3: case 4: case 5:
  95.                 /* OBP */
  96.                 sendbp(sp, sq, crew[0]*100+crew[1]*10+crew[2],
  97.                     0);
  98.                 crew[0] = crew[1] = crew[2] = 0;
  99.                 break;
  100.             }
  101.         }
  102.     }
  103. }
  104.  
  105. fightitout(from, to, key)
  106. struct ship *from, *to;
  107. int key;
  108. {
  109.     struct ship *fromcap, *tocap;
  110.     int crewfrom[3], crewto[3], menfrom, mento;
  111.     int pcto, pcfrom, fromstrength, strengthto, frominjured, toinjured;
  112.     int topoints;
  113.     int index, totalfrom = 0, totalto = 0;
  114.     int count;
  115.     char message[60];
  116.  
  117.     menfrom = mensent(from, to, crewfrom, &fromcap, &pcfrom, key);
  118.     mento = mensent(to, from, crewto, &tocap, &pcto, 0);
  119.     if (fromcap == 0)
  120.         fromcap = from;
  121.     if (tocap == 0)
  122.         tocap = to;
  123.     if (key) {
  124.         if (!menfrom) {         /* if crew surprised */
  125.             if (fromcap == from)
  126.                 menfrom = from->specs->crew1
  127.                     + from->specs->crew2
  128.                     + from->specs->crew3;
  129.             else
  130.                 menfrom = from->file->pcrew;
  131.         } else {
  132.             menfrom *= 2;    /* DBP's fight at an advantage */
  133.         }
  134.     }
  135.     fromstrength = menfrom * fromcap->specs->qual;
  136.     strengthto = mento * tocap->specs->qual;
  137.     for (count = 0;
  138.          (fromstrength < strengthto * 3 && strengthto < fromstrength * 3
  139.           || fromstrength == -1) && count < 4;
  140.          count++) {
  141.         index = fromstrength/10;
  142.         if (index > 8)
  143.             index = 8;
  144.         toinjured = MT[index][2 - die() / 3];
  145.         totalto += toinjured;
  146.         index = strengthto/10;
  147.         if (index > 8)
  148.             index = 8;
  149.         frominjured = MT[index][2 - die() / 3];
  150.         totalfrom += frominjured;
  151.         menfrom -= frominjured;
  152.         mento -= toinjured;
  153.         fromstrength = menfrom * fromcap->specs->qual;
  154.         strengthto = mento * tocap->specs->qual;
  155.     }
  156.     if (fromstrength >= strengthto * 3 || count == 4) {
  157.         unboard(to, from, 0);
  158.         subtract(from, totalfrom, crewfrom, fromcap, pcfrom);
  159.         subtract(to, totalto, crewto, tocap, pcto);
  160.         makesignal(from, "boarders from %s repelled", to);
  161.         (void) sprintf(message, "killed in melee: %d.  %s: %d",
  162.             totalto, from->shipname, totalfrom);
  163.         Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0);
  164.         if (key)
  165.             return 1;
  166.     } else if (strengthto >= fromstrength * 3) {
  167.         unboard(from, to, 0);
  168.         subtract(from, totalfrom, crewfrom, fromcap, pcfrom);
  169.         subtract(to, totalto, crewto, tocap, pcto);
  170.         if (key) {
  171.             if (fromcap != from)
  172.                 Write(W_POINTS, fromcap, 0,
  173.                     fromcap->file->points -
  174.                         from->file->struck
  175.                         ? from->specs->pts
  176.                         : 2 * from->specs->pts,
  177.                     0, 0, 0);
  178.  
  179. /* ptr1 points to the shipspec for the ship that was just unboarded.
  180.    I guess that what is going on here is that the pointer is multiplied
  181.    or something. */
  182.  
  183.             Write(W_CAPTURED, from, 0, to->file->index, 0, 0, 0);
  184.             topoints = 2 * from->specs->pts + to->file->points;
  185.             if (from->file->struck)
  186.                 topoints -= from->specs->pts;
  187.             Write(W_POINTS, to, 0, topoints, 0, 0, 0);
  188.             mento = crewto[0] ? crewto[0] : crewto[1];
  189.             if (mento) {
  190.                 subtract(to, mento, crewto, tocap, pcto);
  191.                 subtract(from, - mento, crewfrom, to, 0);
  192.             }
  193.             (void) sprintf(message, "captured by the %s!",
  194.                 to->shipname);
  195.             Write(W_SIGNAL, from, 1, (int) message, 0, 0, 0);
  196.             (void) sprintf(message, "killed in melee: %d.  %s: %d",
  197.                 totalto, from->shipname, totalfrom);
  198.             Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0);
  199.             mento = 0;
  200.             return 0;
  201.         }
  202.     }
  203.     return 0;
  204. }
  205.  
  206. resolve()
  207. {
  208.     int thwart;
  209.     register struct ship *sp, *sq;
  210.  
  211.     foreachship(sp) {
  212.         if (sp->file->dir == 0)
  213.             continue;
  214.         for (sq = sp + 1; sq < ls; sq++)
  215.             if (sq->file->dir && meleeing(sp, sq) && meleeing(sq, sp))
  216.                 (void) fightitout(sp, sq, 0);
  217.         thwart = 2;
  218.         foreachship(sq) {
  219.             if (sq->file->dir && meleeing(sq, sp))
  220.                 thwart = fightitout(sp, sq, 1);
  221.             if (!thwart)
  222.                 break;
  223.         }
  224.         if (!thwart) {
  225.             foreachship(sq) {
  226.                 if (sq->file->dir && meleeing(sq, sp))
  227.                     unboard(sq, sp, 0);
  228.                 unboard(sp, sq, 0);
  229.             }
  230.             unboard(sp, sp, 1);
  231.         } else if (thwart == 2)
  232.             unboard(sp, sp, 1);
  233.     }
  234. }
  235.  
  236. compcombat()
  237. {
  238.     register n;
  239.     register struct ship *sp;
  240.     struct ship *closest;
  241.     int crew[3], men = 0, target, temp;
  242.     int r, guns, ready, load, car;
  243.     int index, rakehim, sternrake;
  244.     int shootat, hit;
  245.  
  246.     foreachship(sp) {
  247.         if (sp->file->captain[0] || sp->file->dir == 0)
  248.             continue;
  249.         crew[0] = sp->specs->crew1;
  250.         crew[1] = sp->specs->crew2;
  251.         crew[2] = sp->specs->crew3;
  252.         for (n = 0; n < 3; n++) {
  253.             if (sp->file->OBP[n].turnsent)
  254.                 men += sp->file->OBP[n].mensent;
  255.         }
  256.         for (n = 0; n < 3; n++) {
  257.             if (sp->file->DBP[n].turnsent)
  258.                 men += sp->file->DBP[n].mensent;
  259.         }
  260.         if (men){
  261.             crew[0] = men/100 ? 0 : crew[0] != 0;
  262.             crew[1] = (men%100)/10 ? 0 : crew[1] != 0;
  263.             crew[2] = men%10 ? 0 : crew[2] != 0;
  264.         }
  265.         for (r = 0; r < 2; r++) {
  266.             if (!crew[2])
  267.                 continue;
  268.             if (sp->file->struck)
  269.                 continue;
  270.             if (r) {
  271.                 ready = sp->file->readyR;
  272.                 guns = sp->specs->gunR;
  273.                 car = sp->specs->carR;
  274.             } else {
  275.                 ready = sp->file->readyL;
  276.                 guns = sp->specs->gunL;
  277.                 car = sp->specs->carL;
  278.             }
  279.             if (!guns && !car)
  280.                 continue;
  281.             if ((ready & R_LOADED) == 0)
  282.                 continue;
  283.             closest = closestenemy(sp, r ? 'r' : 'l', 0);
  284.             if (closest == 0)
  285.                 continue;
  286.             if (range(closest, sp) > range(sp, closestenemy(sp, r ? 'r' : 'l', 1)))
  287.                 continue;
  288.             if (closest->file->struck)
  289.                 continue;
  290.             target = range(sp, closest);
  291.             if (target > 10)
  292.                 continue;
  293.             if (!guns && target >= 3)
  294.                 continue;
  295.             load = L_ROUND;
  296.             if (target == 1 && sp->file->loadwith == L_GRAPE)
  297.                 load = L_GRAPE;
  298.             if (target <= 3 && closest->file->FS)
  299.                 load = L_CHAIN;
  300.             if (target == 1 && load != L_GRAPE)
  301.                 load = L_DOUBLE;
  302.             if (load > L_CHAIN && target < 6)
  303.                 shootat = HULL;
  304.             else
  305.                 shootat = RIGGING;
  306.             rakehim = gunsbear(sp, closest)
  307.                 && !gunsbear(closest, sp);
  308.             temp = portside(closest, sp, 1)
  309.                 - closest->file->dir + 1;
  310.             if (temp < 1)
  311.                 temp += 8;
  312.             if (temp > 8)
  313.                 temp -= 8;
  314.             sternrake = temp > 4 && temp < 6;
  315.             index = guns;
  316.             if (target < 3)
  317.                 index += car;
  318.             index = (index - 1) / 3;
  319.             index = index > 8 ? 8 : index;
  320.             if (!rakehim)
  321.                 hit = HDT[index][target-1];
  322.             else
  323.                 hit = HDTrake[index][target-1];
  324.             if (rakehim && sternrake)
  325.                 hit++;
  326.             hit += QUAL[index][capship(sp)->specs->qual - 1];
  327.             for (n = 0; n < 3 && sp->file->captured == 0; n++)
  328.                 if (!crew[n])
  329.                     if (index <= 5)
  330.                         hit--;
  331.                     else
  332.                         hit -= 2;
  333.             if (ready & R_INITIAL) {
  334.                 if (!r)
  335.                     sp->file->readyL &= ~R_INITIAL;
  336.                 else
  337.                     sp->file->readyR &= ~R_INITIAL;
  338.                 if (index <= 3)
  339.                     hit++;
  340.                 else
  341.                     hit += 2;
  342.             }
  343.             if (sp->file->captured != 0)
  344.                 if (index <= 1)
  345.                     hit--;
  346.                 else
  347.                     hit -= 2;
  348.             hit += AMMO[index][load - 1];
  349.             temp = sp->specs->class;
  350.             if ((temp >= 5 || temp == 1) && windspeed == 5)
  351.                 hit--;
  352.             if (windspeed == 6 && temp == 4)
  353.                 hit -= 2;
  354.             if (windspeed == 6 && temp <= 3)
  355.                 hit--;
  356.             if (hit >= 0) {
  357.                 if (load != L_GRAPE)
  358.                     hit = hit > 10 ? 10 : hit;
  359.                 table(shootat, load, hit, closest, sp, die());
  360.             }
  361.         }
  362.     }
  363. }
  364.  
  365. next()
  366. {
  367.     if (++turn % 55 == 0)
  368.         if (alive)
  369.             alive = 0;
  370.         else
  371.             people = 0;
  372.     if (people <= 0 || windspeed == 7) {
  373.         register struct ship *s;
  374.         struct ship *bestship;
  375.         float net, best = 0.0;
  376.         foreachship(s) {
  377.             if (*s->file->captain)
  378.                 continue;
  379.             net = (float)s->file->points / s->specs->pts;
  380.             if (net > best) {
  381.                 best = net;
  382.                 bestship = s;
  383.             }
  384.         }
  385.         if (best > 0.0) {
  386.             char *p = getenv("WOTD");
  387.             if (p == 0)
  388.                 p = "Driver";
  389.             if (islower(*p))
  390.                 *p = toupper(*p);
  391.             (void) strncpy(bestship->file->captain, p,
  392.                 sizeof bestship->file->captain);
  393.             bestship->file->captain
  394.                 [sizeof bestship->file->captain - 1] = 0;
  395.             log(bestship);
  396.         }
  397.         return -1;
  398.     }
  399.     Write(W_TURN, SHIP(0), 0, turn, 0, 0, 0);
  400.     if (turn % 7 == 0 && (die() >= cc->windchange || !windspeed)) {
  401.         switch (die()) {
  402.         case 1:
  403.             winddir = 1;
  404.             break;
  405.         case 2:
  406.             break;
  407.         case 3:
  408.             winddir++;
  409.             break;
  410.         case 4:
  411.             winddir--;
  412.             break;
  413.         case 5:
  414.             winddir += 2;
  415.             break;
  416.         case 6:
  417.             winddir -= 2;
  418.             break;
  419.         }
  420.         if (winddir > 8)
  421.             winddir -= 8;
  422.         if (winddir < 1)
  423.             winddir += 8;
  424.         if (windspeed)
  425.             switch (die()) {
  426.             case 1:
  427.             case 2:
  428.                 windspeed--;
  429.                 break;
  430.             case 5:
  431.             case 6:
  432.                 windspeed++;
  433.                 break;
  434.             }
  435.         else
  436.             windspeed++;
  437.         Write(W_WIND, SHIP(0), 0, winddir, windspeed, 0, 0);
  438.     }
  439.     return 0;
  440. }
  441.